home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Tool Chest / Development Kits / MPW etc. / Debuggers / SADE / SADE 1.3.3 / SADE Example Scripts / MiscProcs next >
Encoding:
Text File  |  1991-07-29  |  5.5 KB  |  165 lines  |  [TEXT/sade]

  1. #    Symbolic Application Debugging Environment    1.3 Final
  2. #
  3. #    Copyright Apple Computer, Inc. 1987-1991
  4. #    All rights reserved.
  5. ###############################################################################
  6. # displays the title of each window in the window list.
  7. proc displaywindowlist; 
  8.  
  9. define awindow;            # used to contain the pointer to each window record in turn
  10.  
  11.     awindow := ^WindowRecord(windowlist);    # start at the first window, pointed to from low memory.
  12.     while (awindow <> 0) do    # a NIL terminated list.
  13.         printf ("Window Title = \"%P\"\n",^pString(awindow^.titleHandle^)^);        # write the information out.                                
  14.         awindow := ^WindowRecord(awindow^.nextWindow);        # point at the next in the list.
  15.     end;    
  16.  
  17. end; # displaywindowlist
  18.  
  19.  
  20. ###############################################################################
  21. # a small set of routines to list out all of the FCBs
  22.  
  23. #-------------------------------------------------------------------------------------------
  24. #    FCBLen --     returns the length of the FCB, 20 if we are running MFS (which we won't ever be)
  25. #                or what's in $3F6 if HFS.
  26. #-------------------------------------------------------------------------------------------
  27. func FCBLen    ()
  28.  
  29. define FSFCBLen := ^word($3F6)^                    # fetch value of low-memory global
  30. define MFSFCBLen := 20                            # we know this to be true, for ever and ever
  31.  
  32.     if (FSFCBLen < 0)                             # less than zero means MFS
  33.         return(MFSFCBLen);
  34.     else
  35.         return(FSFCBLen);
  36.     end
  37. end    # func FCBLen
  38.  
  39.  
  40. #-------------------------------------------------------------------------------------------
  41. #    DisplayAnFCB -- displays the entryNumth entry in the FCB table.  Does NOT check to see
  42. #                    if the entry is actually in the table, that's left to the caller
  43. #-------------------------------------------------------------------------------------------
  44. proc DisplayAnFCB(entryNum)
  45.     
  46. define theFCBsAddr,theRefNum
  47. # the following are offsets into the FCB
  48. define fileNumOffset := 0;
  49. define PEOFOffset := 12;
  50. define fileTypeOffset := 50;
  51. define fileNameOffset := 62;
  52.  
  53.     theRefNum := (entryNum * FCBLen()) + 2;     # "+2" accounts for the length word at the
  54.                                                 # start of the FCB block
  55.     theFCBsAddr:= FCBsPtr^+ theRefNum;
  56.     
  57.     printf("$%.4X",theRefNum);                     # print the refnum
  58.     if (theFCBsAddr+fileNumOffset)^ = 0         # the file is unused
  59.         printf("     unused\n");
  60.     else
  61.         printf("     $%.8X",(theFCBsAddr+fileNumOffset)^);    # print the file number
  62.         printf("     $%.8X",(theFCBsAddr+PEOFOffset)^);
  63.         printf("     %#s",(theFCBsAddr+fileTypeOffset)^);
  64.         printf("     %P\n",^pstring(theFCBsAddr+fileNameOffset)^);
  65.     end
  66. END;  # proc DisplayAnFCB
  67.  
  68.  
  69. #-------------------------------------------------------------------------------------------
  70. #    DisplayFCBs -- loops through and lists all FCBs by calling DisplayAnFCB
  71. #-------------------------------------------------------------------------------------------
  72. proc DisplayFCBs
  73.  
  74. # global variable
  75. define global FCBsPtr  := $34E                    # location of pointer to FCBs
  76.  
  77. define i,numFCBs
  78.  
  79.     # print header
  80.     numFCBs:= ^Word(FCBsPtr^)^ / FCBLen();     # we don't really need this variable, but what the hey
  81.     printf("There are %t FCBs starting at $%.8X\n\n",numFCBs,FCBsPtr^);
  82.     printf("RefNum    File#         PEOF          FType    Name\n");
  83.     printf("------    -----         ----          -----    ----\n");
  84.     
  85.     for i:= 0 to numFCBs-1                        # FCB table is zero based
  86.         DisplayAnFCB(i)                          # display this FCB
  87.     end    #for
  88.     undefine FCBsPtr;
  89. end; # proc DisplayFCBs
  90.  
  91.  
  92. ###############################################################################
  93. # this proc creates a listing in the specified output file.
  94. # The listing will have each statement of the specified routine
  95. # followed by a disassembly of the code associated with the statement.
  96. # It isn't very pretty, but it might help you spot code generation bugs.
  97. # Note that the routine to be listed must be in a loaded segment. 
  98.     proc InterList(myRoutine,myOutput)
  99.         open myOutput; redirect myOutput
  100.         define looper := 0, junk
  101.         define currentLine, previousLine, lastLine
  102.         currentLine := eval(concat (myroutine,'.(looper)'), '???')    # start with statement 0
  103.             if (TypeOf(currentLine) = 'PString')
  104.                 printf "cannot find program symbol âˆ‚"%t∂"\n",myroutine
  105.                 redirect pop
  106.                 return
  107.             end
  108.         junk := addrtosource(currentLine)                                        # select the statement
  109.             if (junk != 1)
  110.                 printf "cannot find the source for âˆ‚"%t∂"\n",myRoutine
  111.                 redirect pop
  112.                 return
  113.             end
  114.         selection(targetwindow)                                                            # echo the statement
  115.         disasm currentLine..eval(concat (myroutine,'.(looper+1)'))-1 # add the instructions
  116.         " "
  117.         lastLine := eval(concat (myroutine,'.(1000000)'))        # so we can detect the end
  118.         for looper := 1 to 1000000
  119.             previousLine := eval(concat (myroutine,'.(looper-1)')) # so we can detect duplicates
  120.             leave if ( previousLine = lastLine)                                # all done
  121.             currentLine := eval(concat (myroutine,'.(looper)'))
  122.             if (currentLine != previousLine)                                    # if not a duplicate
  123.                 junk := addrtosource(currentLine)
  124.                 selection(targetWindow)
  125.                 " "
  126.                 disasm currentLine..eval(concat (myroutine,'.(looper+1)'))-1
  127.                 " "
  128.             end
  129.         end
  130.         redirect pop
  131.     end
  132.  
  133.  
  134. # example usage
  135.  
  136. # InterList('routinename','filename')
  137.  
  138.  
  139. ###############################################################################
  140. # for the numerically minded--how many debuggers can do factorial?
  141.  
  142. func fact(n)
  143.     if n <= 1.0 then
  144.         return 1.0
  145.     else
  146.         return n * fact(n-1)
  147.     end
  148. end
  149.  
  150.  
  151. proc factorial (n,file)
  152.     define i
  153.     if nargs>1 then
  154.         redirect file
  155.     end
  156.     for i := 1 to n do
  157.         printf("fact(%.2d) = %19.19g\n",i,fact(i))
  158.     end
  159.     if nargs>1 then
  160.         redirect
  161.     end
  162. end
  163.  
  164.  
  165.